home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 68K / Mac / scripts / EditPythonPrefs.py < prev    next >
Text File  |  1996-05-20  |  8KB  |  340 lines

  1. """Edit the Python Preferences file."""
  2. #
  3. # This program is getting more and more clunky. It should really
  4. # be rewritten in a modeless way some time soon.
  5.  
  6. from Dlg import *
  7. from Events import *
  8. from Res import *
  9. import string
  10. import struct
  11. import macfs
  12. import MacOS
  13. import os
  14. import sys
  15. import Res # For Res.Error
  16.  
  17. # resource IDs in our own resources (dialogs, etc)
  18. MESSAGE_ID = 256
  19.  
  20. DIALOG_ID = 512
  21. TEXT_ITEM = 1
  22. OK_ITEM = 2
  23. CANCEL_ITEM = 3
  24. DIR_ITEM = 4
  25. TITLE_ITEM = 5
  26. OPTIONS_ITEM = 7
  27.  
  28. # The options dialog. There is a correspondence between
  29. # the dialog item numbers and the option.
  30. OPT_DIALOG_ID = 513
  31. # 1 thru 7 are the options
  32. OD_OK_ITEM = 8
  33. OD_CANCEL_ITEM = 9
  34.  
  35. # Resource IDs in the preferences file
  36. PATH_STRINGS_ID = 128
  37. DIRECTORY_ID = 128
  38. OPTIONS_ID = 128
  39.  
  40. # Override IDs (in the applet)
  41. OVERRIDE_PATH_STRINGS_ID = 129
  42. OVERRIDE_DIRECTORY_ID = 129
  43. OVERRIDE_OPTIONS_ID = 129
  44.  
  45. READ = 1
  46. WRITE = 2
  47. smAllScripts = -3
  48. kOnSystemDisk = 0x8000
  49.  
  50. def restolist(data):
  51.     """Convert STR# resource data to a list of strings"""
  52.     if not data:
  53.         return []
  54.     num, = struct.unpack('h', data[:2])
  55.     data = data[2:]
  56.     rv = []
  57.     for i in range(num):
  58.         strlen = ord(data[0])
  59.         if strlen < 0: strlen = strlen + 256
  60.         str = data[1:strlen+1]
  61.         data = data[strlen+1:]
  62.         rv.append(str)
  63.     return rv
  64.     
  65. def listtores(list):
  66.     """Convert a list of strings to STR# resource data"""
  67.     rv = struct.pack('h', len(list))
  68.     for str in list:
  69.         rv = rv + chr(len(str)) + str
  70.     return rv
  71.  
  72. def message(str = "Hello, world!", id = MESSAGE_ID):
  73.     """Show a simple alert with a text message"""
  74.     d = GetNewDialog(id, -1)
  75.     d.SetDialogDefaultItem(1)
  76.     print 'd=', d
  77.     tp, h, rect = d.GetDialogItem(2)
  78.     SetDialogItemText(h, str)
  79.     while 1:
  80.         n = ModalDialog(None)
  81.         if n == 1: break
  82.         
  83. def optinteract(options):
  84.     """Let the user interact with the options dialog"""
  85.     old_options = options[:]
  86.     d = GetNewDialog(OPT_DIALOG_ID, -1)
  87.     d.SetDialogDefaultItem(OD_OK_ITEM)
  88.     d.SetDialogCancelItem(OD_CANCEL_ITEM)
  89.     while 1:
  90.         for i in range(len(options)):
  91.             tp, h, rect = d.GetDialogItem(i+1)
  92.             h.as_Control().SetControlValue(options[i])
  93.         n = ModalDialog(None)
  94.         if n == OD_OK_ITEM:
  95.             return options
  96.         elif n == OD_CANCEL_ITEM:
  97.             return old_options
  98.         elif 1 <= n <= len(options):
  99.             options[n-1] = (not options[n-1])
  100.  
  101.             
  102. def interact(list, pythondir, options, title):
  103.     """Let the user interact with the dialog"""
  104.     opythondir = pythondir
  105.     try:
  106.         # Try to go to the "correct" dir for GetDirectory
  107.         os.chdir(pythondir.as_pathname())
  108.     except os.error:
  109.         pass
  110.     d = GetNewDialog(DIALOG_ID, -1)
  111.     tp, h, rect = d.GetDialogItem(TITLE_ITEM)
  112.     SetDialogItemText(h, title)
  113.     tp, h, rect = d.GetDialogItem(TEXT_ITEM)
  114.     SetDialogItemText(h, string.joinfields(list, '\r'))
  115. ##    d.SetDialogDefaultItem(OK_ITEM)
  116.     d.SetDialogCancelItem(CANCEL_ITEM)
  117.     while 1:
  118.         n = ModalDialog(None)
  119.         if n == OK_ITEM:
  120.             break
  121.         if n == CANCEL_ITEM:
  122.             return None
  123. ##        if n == REVERT_ITEM:
  124. ##            return [], pythondir
  125.         if n == DIR_ITEM:
  126.             fss, ok = macfs.GetDirectory('Select python home folder:')
  127.             if ok:
  128.                 pythondir = fss
  129.         if n == OPTIONS_ITEM:
  130.             options = optinteract(options)
  131.     tmp = string.splitfields(GetDialogItemText(h), '\r')
  132.     rv = []
  133.     for i in tmp:
  134.         if i:
  135.             rv.append(i)
  136.     return rv, pythondir, options
  137.     
  138. def getprefpath(id):
  139.     # Load the path and directory resources
  140.     try:
  141.         sr = GetResource('STR#', id)
  142.     except (MacOS.Error, Res.Error):
  143.         return None, None
  144.     d = sr.data
  145.     l = restolist(d)
  146.     return l, sr
  147.  
  148. def getprefdir(id):
  149.     try:
  150.         dr = GetResource('alis', id)
  151.         fss, fss_changed = macfs.RawAlias(dr.data).Resolve()
  152.     except (MacOS.Error, Res.Error):
  153.         return None, None, 1
  154.     return fss, dr, fss_changed
  155.  
  156. def getoptions(id):
  157.     try:
  158.         opr = GetResource('Popt', id)
  159.     except (MacOS.Error, Res.Error):
  160.         return [0]*7, None
  161.     return map(lambda x: ord(x), opr.data), opr
  162.     
  163. def openpreffile(rw):
  164.     # Find the preferences folder and our prefs file, create if needed.    
  165.     vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0)
  166.     preff_fss = macfs.FSSpec((vrefnum, dirid, 'Python Preferences'))
  167.     try:
  168.         preff_handle = FSpOpenResFile(preff_fss, rw)
  169.     except Res.Error:
  170.         # Create it
  171.         message('No preferences file, creating one...')
  172.         FSpCreateResFile(preff_fss, 'Pyth', 'pref', smAllScripts)
  173.         preff_handle = FSpOpenResFile(preff_fss, rw)
  174.     return preff_handle
  175.     
  176. def openapplet(name):
  177.     fss = macfs.FSSpec(name)
  178.     try:
  179.         app_handle = FSpOpenResFile(fss, WRITE)
  180.     except Res.Error:
  181.         message('File does not have a resource fork.')
  182.         sys.exit(0)
  183.     return app_handle
  184.         
  185.     
  186. def edit_preferences():
  187.     preff_handle = openpreffile(WRITE)
  188.     
  189.     l, sr = getprefpath(PATH_STRINGS_ID)
  190.     if l == None:    
  191.         message('Cannot find any sys.path resource! (Old python?)')
  192.         sys.exit(0)
  193.         
  194.     fss, dr, fss_changed = getprefdir(DIRECTORY_ID)
  195.     if fss == None:
  196.         fss = macfs.FSSpec(os.getcwd())
  197.         fss_changed = 1
  198.         
  199.     options, opr = getoptions(OPTIONS_ID)
  200.     saved_options = options[:]
  201.     
  202.     # Let the user play away
  203.     result = interact(l, fss, options, 'System-wide preferences')
  204.     
  205.     # See what we have to update, and how
  206.     if result == None:
  207.         sys.exit(0)
  208.         
  209.     pathlist, nfss, options = result
  210.     if nfss != fss:
  211.         fss_changed = 1
  212.         
  213.     if fss_changed:
  214.         alias = nfss.NewAlias()
  215.         if dr:
  216.             dr.data = alias.data
  217.             dr.ChangedResource()
  218.         else:
  219.             dr = Resource(alias.data)
  220.             dr.AddResource('alis', DIRECTORY_ID, '')
  221.             
  222.     if pathlist != l:
  223.         if pathlist == []:
  224.             if sr.HomeResFile() == preff_handle:
  225.                 sr.RemoveResource()
  226.         elif sr.HomeResFile() == preff_handle:
  227.             sr.data = listtores(pathlist)
  228.             sr.ChangedResource()
  229.         else:
  230.             sr = Resource(listtores(pathlist))
  231.             sr.AddResource('STR#', PATH_STRINGS_ID, '')
  232.             
  233.     if options != saved_options:
  234.         newdata = reduce(lambda x, y: x+chr(y), options, '')
  235.         if opr and opr.HomeResFile() == preff_handle:
  236.             opr.data = newdata
  237.             opr.ChangedResource()
  238.         else:
  239.             opr = Resource(newdata)
  240.             opr.AddResource('Popt', OPTIONS_ID, '')
  241.                 
  242.     CloseResFile(preff_handle)
  243.     
  244. def edit_applet(name):
  245.     pref_handle = openpreffile(READ)
  246.     app_handle = openapplet(name)
  247.     
  248.     notfound = ''
  249.     l, sr = getprefpath(OVERRIDE_PATH_STRINGS_ID)
  250.     if l == None:
  251.         notfound = 'path'
  252.         
  253.         l, dummy = getprefpath(PATH_STRINGS_ID)
  254.         if l == None:    
  255.             message('Cannot find any sys.path resource! (Old python?)')
  256.             sys.exit(0)
  257.         
  258.     fss, dr, fss_changed = getprefdir(OVERRIDE_DIRECTORY_ID)
  259.     if fss == None:
  260.         if notfound:
  261.             notfound = notfound + ', directory'
  262.         else:
  263.             notfound = 'directory'
  264.         fss, dummy, dummy2 = getprefdir(DIRECTORY_ID)
  265.         if fss == None:
  266.             fss = macfs.FSSpec(os.getcwd())
  267.             fss_changed = 1
  268.  
  269.     options, opr = getoptions(OVERRIDE_OPTIONS_ID)
  270.     if not opr:
  271.         if notfound:
  272.             notfound = notfound + ', options'
  273.         else:
  274.             notfound = 'options'
  275.         options, dummy = getoptions(OPTIONS_ID)
  276.     saved_options = options[:]
  277.     
  278.     dummy = dummy2 = None # Discard them.
  279.     
  280.     if notfound:
  281.         message('Warning: initial %s taken from system-wide defaults'%notfound)
  282.     # Let the user play away
  283.     result = interact(l, fss, options, name)
  284.     
  285.     # See what we have to update, and how
  286.     if result == None:
  287.         sys.exit(0)
  288.         
  289.     pathlist, nfss, options = result
  290.     if nfss != fss:
  291.         fss_changed = 1
  292.         
  293.     if fss_changed:
  294.         alias = nfss.NewAlias()
  295.         if dr:
  296.             dr.data = alias.data
  297.             dr.ChangedResource()
  298.         else:
  299.             dr = Resource(alias.data)
  300.             dr.AddResource('alis', OVERRIDE_DIRECTORY_ID, '')
  301.             
  302.     if pathlist != l:
  303.         if pathlist == []:
  304.             if sr.HomeResFile() == app_handle:
  305.                 sr.RemoveResource()
  306.         elif sr and sr.HomeResFile() == app_handle:
  307.             sr.data = listtores(pathlist)
  308.             sr.ChangedResource()
  309.         else:
  310.             sr = Resource(listtores(pathlist))
  311.             sr.AddResource('STR#', OVERRIDE_PATH_STRINGS_ID, '')
  312.             
  313.     if options != saved_options:
  314.         newdata = reduce(lambda x, y: x+chr(y), options, '')
  315.         if opr and opr.HomeResFile() == app_handle:
  316.             opr.data = newdata
  317.             opr.ChangedResource()
  318.         else:
  319.             opr = Resource(newdata)
  320.             opr.AddResource('Popt', OVERRIDE_OPTIONS_ID, '')
  321.                 
  322.     CloseResFile(app_handle)
  323.  
  324. def main():
  325.     try:
  326.         h = OpenResFile('EditPythonPrefs.rsrc')
  327.     except Res.Error:
  328.         pass    # Assume we already have acces to our own resource
  329.     
  330.     if len(sys.argv) <= 1:
  331.         edit_preferences()
  332.     else:
  333.         for appl in sys.argv[1:]:
  334.             edit_applet(appl)
  335.         
  336.  
  337. if __name__ == '__main__':
  338.     print # Stupid, to init toolboxes...
  339.     main()
  340.